﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;

namespace GoodStuff.SharePoint2007
{
    /// <summary>
    /// Custom implementation of a SiteMapPath which hide itself when there is only one item to show. That probably is the root site.
    /// </summary>
    /// <remarks>
    /// What is the use of a breadcrumb containing only the homepage as item?
    /// </remarks>
    public class BreadCrumbs : SiteMapPath
    {
        /// <summary>
        /// Counterplaceholder that counts the 'real' items that (maybe) are gonna be displayed
        /// </summary>
        private int itemCounter = 0;

        /// <summary>
        /// Default constructor
        /// </summary>
        public BreadCrumbs()
        {
            //Some default properties
            this.HideWhenOnlyOneItemIsRendered = true;
            this.UseLowerCaseHyperlinks = true;
        }

        /// <summary>
        /// Hide the full breadcrumbs when only one item is rendered. (default true)
        /// </summary>
        public bool HideWhenOnlyOneItemIsRendered { get; set; }

        /// <summary>
        /// Renders all hyperlinks in lowercase. SharePoint sometimes causes the sitemap/navigation to render hyperlinks in capital. See http://support.microsoft.com/kb/953457 for more information. (default is true)
        /// </summary>
        public bool UseLowerCaseHyperlinks { get; set; }

        /// <summary>
        /// CreateChildControls
        /// </summary>
        protected override void CreateChildControls()
        {
            //first connect to the event
            this.ItemCreated += new SiteMapNodeItemEventHandler(BreadCrumbs_ItemCreated);

            //Then let the baseclass add it's controls. For each item that is gonna be created,
            //we will handle the event.
            base.CreateChildControls();
        }

        /// <summary>
        /// Event for each item added to the breadcrumbscollection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void BreadCrumbs_ItemCreated(object sender, SiteMapNodeItemEventArgs e)
        {
            // Only counts the items, not the seperators
            if (e.Item.ItemType != SiteMapNodeItemType.PathSeparator)
            {
                //We want to maintain the amount of items that are displayed. All itemTypes except 
                //PathSeparator are 'real' items.
                itemCounter++;

                /* What about the fact that sometimes http://www.myweb.com/SUBSITE url's with capital are rendered?
                 * 
                 * http://support.microsoft.com/kb/953457
                 * This behavior occurs because the navigation functionality in SharePoint Server 2007 depends on 
                 * an underlying cache that is shared by many features. The cache converts all URLs to uppercase 
                 * to perform a case-insensitive hash operation. Then, the cache stores the uppercase URLs to avoid 
                 * performing repeated uppercase conversions. Therefore, in certain situations, uppercase URLs are 
                 * displayed in the rendered navigation links.
                 * ==> We perform a .ToLower() on the url of all hyperlinks we render */
                if (this.UseLowerCaseHyperlinks)
                {
                    e.Item.SiteMapNode.Url = e.Item.SiteMapNode.Url.ToLower();
                }
            }
        }

        /// <summary>
        /// Hide itself when there is only one (or zero) items.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            //First let the base do it's thing
            base.OnPreRender(e);

            if (HideWhenOnlyOneItemIsRendered)
            {
                //Hide the full control when there is only one item
                //or
                //Show the full control when there is more then one item
                this.Visible = this.itemCounter > 1;
            }
        }


    }
}
